home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
csrc720j.lzh
/
amiga.c
next >
Wrap
C/C++ Source or Header
|
1993-08-23
|
35KB
|
1,260 lines
/*
* AMIGA.C - 19th Aug 1988 - System dependent functions.
* Pete Hardie VE5VA
*
*/
#include "mb.h"
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/text.h>
#include <devices/serial.h>
#include <ctype.h>
#include <time.h>
#include "rexxhostbase.h"
extern struct RexxHost *rexx_host;
extern long rexxbit;
extern struct Window *mywindow;
extern struct IntuiMessage *NewMessage;
short interflag = 0;
short debug;
long serfirst = 0L;
char tmpstr[300];
extern struct IOExtSer *Ser_Read;
extern struct IOStdReq *Con_Read,*Con_Write;
extern unsigned char rs_in[2];
extern struct IOExtSer *Ser_Write;
extern unsigned char rs_out[2];
extern char optflags[];
unsigned char gotstream = 0;
extern char *tcmds[];
/*
{
"cono on\n",
"cono of\n",
"m on\n",
"m of\n"
};
*/
char passchr = 0,hfstream = 0,vhfstream = 0;
char l_date[7], l_time[5];
char z_date[7], z_time[5];
char pt_flag = 0;
extern short tapr_flag;
short done_flag = 1;
/*
* Set the current I/O device.
*/
ioport(pp)
PORTS *pp;
{
port = pp;
}
/*
* Return non-zero if a character waits at current input.
*/
instat()
{
register int st;
if (port->dev is p_console) {
/* check for char at console */
if(CheckIO((struct IORequest *)Con_Read))return(1);
else return(0);
}
if(port->dev is p_tnc) {
/* check for char at serial port */
if(CheckIO((struct IORequest *)Ser_Read)) {
if(optflags[4])interflag = 1;
return(1);
}
else return(0);
}
return(0);
}
/* output char to serial port */
outi(ch)
char ch;
{
schar(ch);
}
/*
* Put the character out the current port,
* echo to console if the current port is not the console.
* Note special handling of end-of-line character.
*/
outchar(ch)
char ch;
{
if (ch is '\r') return;
if (ch is '\n') ch = '\r';
/*
* Put it out to the console, if it is going there.
*/
if ((port->dev is p_console) or port->ec) {
if (ch is '\r') ttputc('\n');/* output '\n' */;
if(ch != passchr)ttputc(ch);
}
/*
* If the port is the console, nothing more to do.
*/
if (port->dev is p_console) return;
/*
* Stuff this byte out the port.
*/
outi(ch);
if (ch is '\r')
if (port->flags & p_lf) outi('\n');
}
unsigned char procstr[linelen];
/* This routine must not use tmpstr to process the string because tmpstr
might be the input
*/
outstr(cp)
unsigned char *cp;
{
register unsigned char *p,*q;
register int beepcount;
/* count the number of beeps in the line so that we can give an audible
as well as visual beep
*/
if((port->dev is p_console) || port->ec) {
beepcount = 0;
for(q = cp,p = &procstr[0];*q && p < &procstr[linelen-1];q++) {
if(*q is '\r')continue;
*p++ = *q;
if(*q == '\007')beepcount++;
}
*p = 0;
Con_Write->io_Data = (APTR) &procstr[0];
Con_Write->io_Length = p-&procstr[0];
Con_Write->io_Command = CMD_WRITE;
DoIO((struct IORequest *)Con_Write);
while(beepcount--) {
beep();
Delay(15L);
}
}
/* now do the TNC if it is required.
The TNC appears to drop characters if I send the whole line
in one I/O so leave it at one character at a time. At 1200
baud this is not a problem.
*/
if(port->dev is p_console)return;
for(q = cp,p = &procstr[0];*q && p < &procstr[linelen-1];q++) {
if(*q is '\r')continue;
if(*q is '\n') {
*p++ = '\r';
if (port->flags & p_lf)*p++ = '\n';
}
else *p++ = *q;
}
*p = 0;
Ser_Write->IOSer.io_Command = CMD_WRITE;
Ser_Write->IOSer.io_Length = p-&procstr[0];
Ser_Write->IOSer.io_Data = (APTR) &procstr[0];
DoIO((struct IORequest *)Ser_Write);
}
short wait_timeout = 0;
char cmdstring[100];
FILE *fd;
PORTS *devtnc;
char *inittnc(infile,force)
int force;
char *infile;
{
/* This routine MUST NOT use tmpstr while the infile string is being used.
infile could be the tmpstr!
*/
register char *cp;
register char c;
register PORTS *p;
PORTS *oldport;
oldport = port;
wait_timeout = 0;
devtnc = 0;
/* Find the tnc port and set it as the current port */
for(p=porthd; p != NULL; p = p->next) {
if((devtnc == 0) && (p->id != 'Z'))devtnc = p;
}
if(devtnc == 0) {
printf("Can't find port\n");
donebeep();
endtimer();
cleanser();
freefcb();
closeterm();
clrbusy();
exit(1);
}
ioport(devtnc);
if((devtnc->dev == p_serial) || (devtnc->dev == p_nulmdm)) {
devtnc->ec = 1;
goto file_only;
}
if(!force)goto file_only;
/* Force a ^Q^C X to the KAM or other TNC. If KAM is in mode other
than packet this will force it back.
If already in packet mode this will be interpreted as an XFLOW
request ... which won't hurt anything
*/
outstr("\021\003X\n\n");
waitcmd(10);
/* have to turn off monitoring and conok so that nothing interferes
with the startup
*/
alloff();
outstr("echo off\n"); /* echo MUST be off too */
waitcmd(10);
/* If wait_timeout is too big then the TNC probably isn't there
so let's get outta here
*/
if(wait_timeout >= 3) {
fclose(port->fl);
donebeep();
endtimer();
cleanser();
freefcb();
closeterm();
clrbusy();
printf("Too many timeouts from TNC - possible reasons are:\n");
printf("1. TNC and AMIGA are not using same baudrate\n");
printf("2. The TNC is not plugged into the AMIGA\n");
printf("3. The TNC PARITY is not set to NONE (or SPACE)\n");
printf("4. There's too much monitored information buffered\n");
printf(" and it took too long to clear it - try again\n");
exit(1);
}
/* get the thing into sync with what comes in from the TNC which
may have stored up a lot of monitored stuff
Do this by sending out a command and watch for the reply.
*/
outstr("txd\n");
do {
if((c = toupper(rdchar())) != 'T') {
ttputc(c);
continue;
}
ttputc('T');
if((c = toupper(rdchar())) != 'X') {
ttputc(c);
continue;
}
ttputc('X');
if((c = toupper(rdchar())) != 'D') {
ttputc(c);
continue;
}
ttputc('D');
break;
}while(1);
waitcmd(0);
if(!passchr) {
outstr("pass\n");
while((c = toupper(rdchar())) != 'P') {
ttputc(c);
/* If the reply contains '?' then there's no pass command */
if(c == '?') {
ttputs("NO PASS COMMAND\n\n");
goto file_only;
}
}
ttputc(c);
while((c = toupper(rdchar())) != '$')ttputc(c);
ttputc(c);
ttputc(c = rdchar());
passchr = hex(c) << 4;
ttputc(c = rdchar());
passchr |= hex(c);
waitcmd(0);
}
/* Now find out what the stream switching character(s) is(are) */
/* but forget it if there is no pass char */
if(passchr && !hfstream && !vhfstream) { /* if not done before */
outstr("streamsw\n");
while((c = toupper(rdchar())) != 'W') {
ttputc(c);
if(c == '?') {
/* something's gone wrong. If there is a passchar then there
must also be a streamswitch. If not then clear passchr and
announce the problem
*/
passchr = 0;
ttputs("Error from STREAMSW command - streamswitching off\n");
waitcmd(0);
goto file_only;
}
}
ttputc(c);
while((c = toupper(rdchar())) != '$')ttputc(c);
ttputc(c);
ttputc(c = rdchar());
vhfstream = hex(c) << 4;
ttputc(c = rdchar());
vhfstream |= hex(c);
/* IF it is a KAM there are two streamswitching chars to read */
if((c = rdchar()) == '/') {
ttputc(c);
hfstream = vhfstream;
ttputc(rdchar()); /* do the $ sign */
ttputc(c = rdchar());
vhfstream = hex(c) << 4;
ttputc(c = rdchar());
vhfstream |= hex(c);
}
else ttputc(c);
waitcmd(0);
}
sprintf(cmdstring,"\nPASS = $%02x, streamswitch VHF = ",passchr);
ttputs(cmdstring);
if((vhfstream > ' ') && (vhfstream < 0177))
sprintf(cmdstring,"%c",vhfstream);
else
sprintf(cmdstring,"$%02x",vhfstream);
ttputs(cmdstring);
if(hfstream) {
if((hfstream > ' ') && (hfstream < 0177))
sprintf(cmdstring," , HF = %c",hfstream);
else
sprintf(cmdstring," , HF = $%02x",hfstream);
ttputs(cmdstring);
}
ttputc('\n');
file_only:
if((fd = fopen(infile,"r")) == NULL) {
sprintf(tmpstr,"Can't open %s\n",infile);
ioport(oldport);
return(tmpstr);
}
while(fgets(cmdstring,99,fd) != NULL) {
/* Ignore blank lines and comments */
if((cmdstring[0] == 0) || (cmdstring[0] == 012)
|| (cmdstring[0] == '#'))continue;
if(cmdstring[0] == '!') {
remnl(&cmdstring[0]);
do_system(&cmdstring[1]);
continue;
}
if(cmdstring[0] == '^') {
/* If it is ^S, send it and don't bother to read any more
of the file as the TNC won't respond anyway
*/
if(toupper(cmdstring[1]) == 'S') {
outchar('\023');
break;
}
/* Ignore anything else. There's no point allowing ^Q because
the startup code at the beginning of inittnc must force ^Q
anyway, otherwise it wouldn't be able to get the tnc to
respond.
*/
continue;
}
outstr(cmdstring);
waitcmd(0);
}
fclose(fd);
ioport(oldport);
return((char *)0);
}
hex(c)
char c;
{
char k;
k = c;
if((c >= '0') && (c <= '9'))return(c - '0');
k = toupper(c);
if((k >= 'A') && (c <= 'F'))return(c - 'A' + 10);
return(-1);
}
flipdebug()
{
debug ^= 1;
if(debug) {
ttputs("debug now ON\n");
}
else {
ttputs("debug now OFF\n");
}
}
extern unsigned char ichar;
extern long keybit,windbit,readbit,timerbit;
long getbits;
struct timeRequest {
struct IORequest tr_node;
struct timeval tr_time;
};
extern struct timeRequest timermsg;
/* replace the original do_idle because it busy-waited ...
this version sleeps until there is something to do
*/
extern short cursecs;
do_idle()
{
register unsigned char ch,*cp;
register PORTS *p;
int curmin,curmon;
ULONG class,error;
UWORD code;
struct RexxMsg *rexxmessage; /* incoming rexx messages */
STRPTR Arg; /* Temporary string pointer */
PORTS *saveport;
long waitbits; /* waitbits MUST be local in CBBS because it is changed
by various other routines as they see fit */
cursor_off();
ioport(devtnc);
allon();
if((devtnc->dev == p_serial) || (devtnc->dev == p_nulmdm)) {
ttputs("\nIDLE\n");
}
cp = (unsigned char *) devtnc->line;
/* figure out time to next forward and set timer */
curtim();
curmin = 60 - cursecs;
settimer(curmin);
/* There might already be an unread char at the serial or console port */
serfirst = 0L;
clrbusy();
if(CheckIO((struct IORequest *)Ser_Read)) {
serfirst |= readbit;
Wait(readbit);
}
if(CheckIO((struct IORequest *)Con_Read)) {
serfirst |= keybit;
Wait(keybit);
}
waitbits = windbit | readbit | timerbit | keybit | rexxbit;
while(1) {
/* If there was already a tnc char waiting then do it now */
if(serfirst) {
getbits = serfirst;
serfirst = 0L;
}
else {
getbits = Wait(waitbits);
}
if(windbit & getbits) {
while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == IDCMP_CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
/* Need this to cancel out the clrbusy in done() */
setbusy();
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == wchar) {
ioport(cport);
cursor_on();
/* could have a timerbit set here.
readbit could also be set but must handle that a
different way.
*/
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
return;
}
if(ch == '\033') {
ttputs("do_idle\n");
}
}
if(readbit & getbits) {
/* save a line and if it is a CONNECT then return */
if(error = WaitIO((struct IORequest *)Ser_Read)) {
printf("DO_IDLE error %ld\n",error);
}
ch = rs_in[0];
if(tapr_flag)ch &= 0177;
*cp = ch; /* autolf is off so don't need to look for '\n' */
if((cp++ == (unsigned char *)devtnc->line + linelen -2)
|| (ch == '\r')) {
if(ch == '\r')cp--;
*cp++ = '\n';
*cp = 0;
/* Str_search cleans up the line and then does outstr */
ioport(cport);
str_search(devtnc->line);
ioport(devtnc);
p->flags setbit p_give;
if(iscon(devtnc->line)) {
/* readbit has been handled but timerbit could be set */
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
BeginIO((struct IORequest *)Ser_Read);
return;
}
monitor();
cp = (unsigned char *)devtnc->line;
}
else if(ch == '\n')cp--;
BeginIO((struct IORequest *)Ser_Read);
}
/* REXX must turn off the clock because the forward may do it
anyway. Then once the forward is over, start the clock up
again.
*/
if(rexxbit & getbits) {
while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
/* If Arg is non-zero then this is an AREXX message from another
process.
If Arg is null then it is the result of a ReplyRexxCommand
from another process. This can't happen yet because we do not
send messages out.
*/
if(Arg = GetRexxCommand(rexxmessage)) {
/* Must turn off the clock because the forward may do it
anyway. Then once the forward is over, start the clock up
again.
*/
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
getbits &= ~timerbit;
saveport = port;
/* Have to force it to use the console port for this */
ioport(cport);
port->opt1 = *Arg++;
port->opt2 = *Arg;
/* Have to reply to it early so that the sysop, or other
process doesn't have to wait for the forward to finish.
Send a non-zero secondary result to indicate OK.
*/
ReplyRexxCommand(rexxmessage,0L,1L,0L);
alloff();
acmd();
allon();
ioport(saveport);
/* Turn clock back on again */
/* figure out time to next forward and set timer */
curtim();
curmin = 60 - cursecs;
settimer(curmin);
}
else {
FreeRexxCommand(rexxmessage);
}
}
}
/* This code is deliberately placed last. If a timer bit occurs
at the same time as a character arrives from the serial port
then this code will hang the serial port up because afwd()
tries to use the port again without clearing the existing char.
So workaround it. Putting the timer code here guarantees that
even if the ser char did occur it will be handled first and the
ser char code handles the problem of returning from this routine
with a timer bit set.
*/
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
/* call the forwarding routine */
curtim();
curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
afwd(curmin);
curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
if (s_param & s_log_on) if (curmon isnt log_mon) chglog();
settimer(60);
}
}
}
/* IMPLEMENTATION BUG. In the original getdat it busy-idles and
if the port is transparent and DCD goes off while the port is
not idle, then it forces the mode to discon and then returns(true).
This code can only do this properly IF it can wait for DCD to go
off. I haven't even tried to implement this yet and not sure if it
can be done properly. I assume that there's a way to Wait() for a
DCD event but haven't checked it out
*/
char *cp;
/* MAXLEN is the longest unterminated line the justification routine
will accept before it rips out the word and keeps it for later use.
MAXJUST is the longest word that the routine will keep ... if the word
is any longer than this then it will just allow you to mess up the line!
*/
#define MAXLEN 77
#define MAXJUST 20
unsigned char x_pos = 0; /* Position on line for right justification */
unsigned char s_pos = 0; /* Position of last space on the line */
char saveword[MAXJUST+2];
getdat()
{
register char *q;
register char ch;
register PORTS *p;
int eflag;
int curmin,serflg;
ULONG class,waitbits;
USHORT code;
p = port;
cp = p->line;
x_pos = s_pos = 0;
/* If there was a justified word left over from previous line .. put it
in here now.
*/
if(*saveword) {
q = saveword;
while(*q) {
ttputc(*q);
*cp++ = *q++;
x_pos++;
}
}
*saveword = 0;
*cp = 0;
/* Is a timeout timer required? */
curmin = 0;
if(p->flags & p_dotmr) {
if((p->mode & idle) && (p->dev == p_tnc))
curmin = 2;
else
curmin = p->ctime;
}
/* The timer counts curmin down and each time it ticks the program
queries the serial driver to see if CD is still on if the user
is logged in on the modem. It doesn't bother for the sysop because
the modem won't be active.
I don't think that p_nulmdm needs to worry about this timer.
*/
if(curmin) {
if(p->dev != p_serial) {
settimer(curmin);
}
else {
settimer(1); /* set timeout timer if required to look for CD */
}
}
p->flags setbit p_dotmr;
serfirst = 0L;
if(CheckIO((struct IORequest *)Ser_Read)) {
serfirst |= readbit;
Wait(readbit);
}
if(p == cport) {
waitbits = windbit | timerbit | keybit;
}
else {
if(CheckIO((struct IORequest *)Con_Read)) {
serfirst |= keybit;
Wait(keybit);
}
waitbits = windbit | readbit | timerbit | keybit;
}
while(1) {
if(serfirst) {
getbits = serfirst;
serfirst = 0L;
}
else {
getbits = Wait(waitbits);
}
if(windbit & getbits) {
while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == IDCMP_CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == '\033') {
if(p == cport)ttputs("getdatCON\n");
else ttputs("getdatTNC\n");
}
eflag = 0;
if(p != cport) {
if(ch == achar) {
p->mode = forced;
eflag = 1;
}
if(ch == tchar) {
p->flags setbit p_opreq;
eflag = 1;
}
}
else {
if(charf(ch)) {
eflag = 1;
}
}
/* If any of the previous three if statements want to
exit then check that the timer is off and then get out
*/
if(eflag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
if(curmin)cantimer();
}
*cp = 0;
return(true);
}
}
if(readbit & getbits) {
WaitIO((struct IORequest *)Ser_Read);
ch = rs_in[0];
if(tapr_flag)ch &= 0177;
BeginIO((struct IORequest *)Ser_Read);
if(optflags[4])interflag = 1;
/* ignore stuff from the port if we are reading the console */
if((p != cport) && charf(ch)) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
if(curmin)cantimer();
}
if(!(p->flags & p_trans)) {
if(isdis(p->line)) {
if(!(p->mode & idle))p->mode = discon;
return (true);
}
if(isretry(p->line)) {
return (false);
}
if(isreq(p->line)) {
p->flags setbit p_req;
pcall(p->rcall,p->line+20);
p->flags clrbit p_dotmr;
return (false);
}
}
return (true);
}
}
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
if((curmin -= 1) <= 0) {
if(!(p->mode & idle))p->mode = timeout;
*cp = 0;
return (true);
}
/* Look for drop of carrier detect on the serial port */
if(p->dev == p_serial) {
if(getserstat() & 0x20) {
p->mode = discon;
*cp = 0;
return(true);
}
}
settimer(1);
}
}
}
charf(s)
unsigned char s;
{
register unsigned char ch;
PORTS *p;
register char *q,*r;
register int i;
p = port;
ch = s;
/* Ignore characters with high order bit set...they tie up the TNC */
if(ch > 0177)return(0);
*cp = ch;
if((cp >= p->line + linelen - 3) || (ch == '\r')) {
do_lf:
if(ch == '\r')*cp = '\n';
*++cp = 0;
if(p->dev != p_console)ttputs(p->line);
if(p->flags & p_echo)ttputc('\n');
return(1);
}
if((ch >= ' ') && (ch <= 0176)) {
/*
Do justification for local user.
*/
if(p->dev == p_console) {
if(ch == ' ') {
s_pos = x_pos;
/* If the space is at exactly the point we would have justified
the line then fake a CR anyway
*/
if(x_pos == MAXLEN) {
ch = '\r';
*saveword = 0;
goto do_lf;
}
}
else {
/* It's not a space ... should we do the justify?
*/
if(x_pos == MAXLEN) {
/* This word can't be longer than MAXJUST or we just leave
it alone and let them mess up the line
*/
if((i = (MAXLEN - s_pos)) < MAXJUST) {
q = saveword;
r = &p->line[s_pos+1];
do {
*q++ = *r++;
ttputs("\b \b");
}while(--i);
*q = 0;
cp = &p->line[s_pos];
ch = '\r';
goto do_lf;
}
}
}
}
x_pos++;
if (p->flags & p_echo) ttputc(ch);
cp++;
return(0);
}
switch(ch) {
default:
break;
case 26: /* Control - Z */
cp++;
x_pos++;
break;
case '\t':
if(p->flags & p_echo) ttputc(ch);
s_pos = x_pos;
x_pos++;
cp++;
break;
case '\b':
if(cp > p->line) {
cp--;
if(p->flags & p_echo) ttputs("\b \b");
x_pos--;
/* If they wipe out a space we've got to find the previous one */
if(*cp == ' ') {
r = cp-1;
while(r > p->line) {
if(*r == ' ') break;
r--;
}
s_pos = r - p->line;
}
}
break;
case '\n':
if(cp is p->line) {
*cp = '\0';
return(1);
}
break;
}
return(0);
}
/* Remove the busy-wait in term() */
term(s)
PORTS *s;
{
register char ch,*cp;
register PORTS *m;
ULONG class,waitbits;
USHORT code;
byte ec;
m = cport;
m->flags clrbit p_give;
ec = s->ec;
s->ec = true;
ioport(m);
serfirst = 0L;
if(CheckIO((struct IORequest *)Ser_Read)) {
serfirst |= readbit;
Wait(readbit);
}
waitbits = windbit | readbit | keybit;
while(1) {
if(serfirst) {
getbits = serfirst;
serfirst = 0L;
}
else {
getbits = Wait(waitbits);
}
if(windbit & getbits) {
while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == IDCMP_CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == rchar) {
m->flags setbit p_give;
s->ec = ec;
return;
}
if(ch == '\r')ch = '\n';
ttputc(ch);
if(ch == '\n') {
schar('\r');
if(s->flags & p_lf)schar('\n');
}
else schar(ch);
if(m->fl isnt NULL) if(ch isnt cpmeof)putc(ch,m->fl);
}
if(readbit & getbits) {
WaitIO((struct IORequest *)Ser_Read);
ch = rs_in[0];
if(tapr_flag)ch &= 0177;
BeginIO((struct IORequest *)Ser_Read);
/* if(streamswitch(ch))continue; */
if(ch == '\r')ch = '\n';
if(m->fl isnt NULL) if(ch isnt cpmeof)putc(ch,m->fl);
ttputc(ch);
}
}
}
/* This handles the stream characters.
BUT not any more ... KAM V3.0 has removed the streamdb command.
The first streamswitch character is always printed but is not passed
as data.
The character immediately after the streamswitch is passed if it is the
same streamswitch character, otherwise it is printed but also not passed
as data.
streamswitch(ch)
unsigned char ch;
{
if(gotstream) {
if(ch == gotstream) {
gotstream = 0;
}
else {
gotstream = 0;
ttputc(ch);
return(1);
}
}
else {
if(ch && ((ch == vhfstream) || (ch == hfstream))) {
gotstream = ch;
ttputc(ch);
return(1);
}
}
return(0);
}
*/
/* Replace the pause routine so that it can be used with TNC as well
as the console. If routine times out after 2 minutes then it will
return 'Q'.
*/
pause()
{
register char ch,*q;
ULONG class,waitbits;
USHORT code;
if (port->user->state & u_pause) return ' ';
q = &tmpstr[0];
prtx(pausemsg);
if(port->mode != local)outchar('\n');
settimer(120); /* set timeout timer */
waitbits = windbit | readbit | timerbit | keybit;
serfirst = 0L;
if(CheckIO((struct IORequest *)Ser_Read)) {
serfirst |= readbit;
Wait(readbit);
}
while(1) {
if(serfirst) {
getbits = serfirst;
serfirst = 0L;
}
else {
getbits = Wait(waitbits);
}
if(windbit & getbits) {
while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == IDCMP_CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = toupper(ichar);
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
outchar('\n');
return(ch);
}
if(readbit & getbits) {
WaitIO((struct IORequest *)Ser_Read);
ch = rs_in[0];
if(tapr_flag)ch &= 0177;
ch = toupper(ch);
BeginIO((struct IORequest *)Ser_Read);
*q++ = ch;
if(ch == '\r') {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
return(tmpstr[0]);
}
}
/* check for timeout */
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
return('Q');
}
}
}
/* Force modem to hangup */
force_modem()
{
/* if(getserstat() & 0x20)return;*/
Delay(150L);
outstr("+++");
waitcmd(5);
Delay(10L);
outstr("ATH0\n");
waitcmd(5);
}
/* Skips leading blanks and then converts next two hex digits to binary.
returns -1 on error.
*/
fromhex(s)
char *s;
{
register int i,j;
register char *p;
p = s;
i = 0;
while(*p == ' ')p++;
if((i = hex(*p++)) < 0)return(-1);
j = hex(*p);
if(j < 0)return(-1);
i <<= 4;
i |= j;
return(i);
}
/* replace waitcmd from mbtnc to reduce busy waits */
char *waitfor = "cmd:";
short wait_read;
waitcmd(x)
int x;
{
register char ch;
register int i;
ULONG class,waitbits;
USHORT code;
wait_read = 0;
if(port->dev == p_nulmdm)return;
if(port->dev == p_serial) {
waitfor = "ok\n\n";
}
else
if(port->dev != p_tnc)return;
if(s_flag & s_dv) i = 5;
else i = 2;
if(x) i = x;
settimer(i); /* set timeout timer */
i = 0;
waitbits = windbit | readbit | timerbit | keybit;
serfirst = 0L;
if(CheckIO((struct IORequest *)Ser_Read)) {
serfirst |= readbit;
Wait(readbit);
}
while(1) {
if(serfirst) {
getbits = serfirst;
serfirst = 0L;
}
else {
getbits = Wait(waitbits);
}
if(windbit & getbits) {
while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == IDCMP_CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == '\033') { /* ESC key forces termination */
ttputs("ESC\n");
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
return;
}
}
if(readbit & getbits) {
WaitIO((struct IORequest *)Ser_Read);
wait_read = 1;
ch = rs_in[0];
if(tapr_flag)ch &= 0177;
BeginIO((struct IORequest *)Ser_Read);
/* if(streamswitch(ch))continue; */
if(ch == '\r') {
ch = '\n';
}
ttputc(ch);
if(tolower(ch) == waitfor[i]) {
i++;
if(i == strlen(waitfor)) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
return;
}
}
else {
i = 0;
}
}
/* check for timeout */
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
wait_timeout++;
return;
}
}
}